From fe60d43a26380580e54ddec62a3746253f07cc0d Mon Sep 17 00:00:00 2001 From: Hans Breuer Date: Thu, 28 Mar 2002 23:25:33 +0000 Subject: [PATCH] Fixed dashed line issues (#74441) to an IMO reasonable extend. That is: 2002-03-29 Hans Breuer Fixed dashed line issues (#74441) to an IMO reasonable extend. That is: use PS_USERSTYLE on WinNT (the next GDI limit appears to be with lines width > 50); Render horizontal and vertical dashed lines on Win9x 'by hand'. Dotted selection rectangles and Dia look nice ... * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and num_pen_dashes to _GdkGCWin32 * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove the guesses from dashes to windoze line styles. (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on Win9x, which does not support PS_USERSTYLE. * gdk/win32/gdkdrawable-win32.c : new functions render_line_ . Use them if not running on NT in gdk_win32_draw_ () * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL for keyval == 0 to avoid to have zeros in all menu entries without accelerator. --- ChangeLog | 22 +++ ChangeLog.pre-2-10 | 22 +++ ChangeLog.pre-2-2 | 22 +++ ChangeLog.pre-2-4 | 22 +++ ChangeLog.pre-2-6 | 22 +++ ChangeLog.pre-2-8 | 22 +++ gdk/win32/gdkdrawable-win32.c | 321 ++++++++++++++++++++++++++-------- gdk/win32/gdkgc-win32.c | 124 ++++++------- gdk/win32/gdkkeys-win32.c | 4 +- gdk/win32/gdkprivate-win32.h | 2 + 10 files changed, 444 insertions(+), 139 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ff5812ae9..8d0fcaffac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2002-03-29 Hans Breuer + + Fixed dashed line issues (#74441) to an IMO reasonable extend. + That is: use PS_USERSTYLE on WinNT (the next GDI limit appears + to be with lines width > 50); Render horizontal and vertical + dashed lines on Win9x 'by hand'. Dotted selection rectangles + and Dia look nice ... + + * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and + num_pen_dashes to _GdkGCWin32 + * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove + the guesses from dashes to windoze line styles. + (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on + Win9x, which does not support PS_USERSTYLE. + * gdk/win32/gdkdrawable-win32.c : new functions render_line_ + . Use them if not running on NT in + gdk_win32_draw_ () + + * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL + for keyval == 0 to avoid to have zeros in all menu entries + without accelerator. + 2002-03-29 Jakub Steiner * gtk/stock-icons/stock_add_24.png: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 2ff5812ae9..8d0fcaffac 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,25 @@ +2002-03-29 Hans Breuer + + Fixed dashed line issues (#74441) to an IMO reasonable extend. + That is: use PS_USERSTYLE on WinNT (the next GDI limit appears + to be with lines width > 50); Render horizontal and vertical + dashed lines on Win9x 'by hand'. Dotted selection rectangles + and Dia look nice ... + + * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and + num_pen_dashes to _GdkGCWin32 + * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove + the guesses from dashes to windoze line styles. + (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on + Win9x, which does not support PS_USERSTYLE. + * gdk/win32/gdkdrawable-win32.c : new functions render_line_ + . Use them if not running on NT in + gdk_win32_draw_ () + + * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL + for keyval == 0 to avoid to have zeros in all menu entries + without accelerator. + 2002-03-29 Jakub Steiner * gtk/stock-icons/stock_add_24.png: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 2ff5812ae9..8d0fcaffac 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,25 @@ +2002-03-29 Hans Breuer + + Fixed dashed line issues (#74441) to an IMO reasonable extend. + That is: use PS_USERSTYLE on WinNT (the next GDI limit appears + to be with lines width > 50); Render horizontal and vertical + dashed lines on Win9x 'by hand'. Dotted selection rectangles + and Dia look nice ... + + * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and + num_pen_dashes to _GdkGCWin32 + * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove + the guesses from dashes to windoze line styles. + (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on + Win9x, which does not support PS_USERSTYLE. + * gdk/win32/gdkdrawable-win32.c : new functions render_line_ + . Use them if not running on NT in + gdk_win32_draw_ () + + * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL + for keyval == 0 to avoid to have zeros in all menu entries + without accelerator. + 2002-03-29 Jakub Steiner * gtk/stock-icons/stock_add_24.png: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 2ff5812ae9..8d0fcaffac 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,25 @@ +2002-03-29 Hans Breuer + + Fixed dashed line issues (#74441) to an IMO reasonable extend. + That is: use PS_USERSTYLE on WinNT (the next GDI limit appears + to be with lines width > 50); Render horizontal and vertical + dashed lines on Win9x 'by hand'. Dotted selection rectangles + and Dia look nice ... + + * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and + num_pen_dashes to _GdkGCWin32 + * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove + the guesses from dashes to windoze line styles. + (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on + Win9x, which does not support PS_USERSTYLE. + * gdk/win32/gdkdrawable-win32.c : new functions render_line_ + . Use them if not running on NT in + gdk_win32_draw_ () + + * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL + for keyval == 0 to avoid to have zeros in all menu entries + without accelerator. + 2002-03-29 Jakub Steiner * gtk/stock-icons/stock_add_24.png: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 2ff5812ae9..8d0fcaffac 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,25 @@ +2002-03-29 Hans Breuer + + Fixed dashed line issues (#74441) to an IMO reasonable extend. + That is: use PS_USERSTYLE on WinNT (the next GDI limit appears + to be with lines width > 50); Render horizontal and vertical + dashed lines on Win9x 'by hand'. Dotted selection rectangles + and Dia look nice ... + + * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and + num_pen_dashes to _GdkGCWin32 + * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove + the guesses from dashes to windoze line styles. + (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on + Win9x, which does not support PS_USERSTYLE. + * gdk/win32/gdkdrawable-win32.c : new functions render_line_ + . Use them if not running on NT in + gdk_win32_draw_ () + + * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL + for keyval == 0 to avoid to have zeros in all menu entries + without accelerator. + 2002-03-29 Jakub Steiner * gtk/stock-icons/stock_add_24.png: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 2ff5812ae9..8d0fcaffac 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,25 @@ +2002-03-29 Hans Breuer + + Fixed dashed line issues (#74441) to an IMO reasonable extend. + That is: use PS_USERSTYLE on WinNT (the next GDI limit appears + to be with lines width > 50); Render horizontal and vertical + dashed lines on Win9x 'by hand'. Dotted selection rectangles + and Dia look nice ... + + * gdk/win32/gdkprivate-win32.h : add pen_dashes pointer and + num_pen_dashes to _GdkGCWin32 + * gdk/win32/gdkgc-win32.c : initialize pen_dashes and remove + the guesses from dashes to windoze line styles. + (predraw_set_forground) : always ExtCreatePen (PS_SOLID) on + Win9x, which does not support PS_USERSTYLE. + * gdk/win32/gdkdrawable-win32.c : new functions render_line_ + . Use them if not running on NT in + gdk_win32_draw_ () + + * gdk/win32/gdkkeys-win32.c (gdk_keyval_name) : return NULL + for keyval == 0 to avoid to have zeros in all menu entries + without accelerator. + 2002-03-29 Jakub Steiner * gtk/stock-icons/stock_add_24.png: diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c index a4dc7298b0..62b9c3f9d4 100644 --- a/gdk/win32/gdkdrawable-win32.c +++ b/gdk/win32/gdkdrawable-win32.c @@ -250,6 +250,69 @@ gdk_win32_set_colormap (GdkDrawable *drawable, /* Drawing */ +/* + * Render a dashed line 'by hand' cause the Win9x GDI is + * too limited to do so + */ +static inline gboolean +render_line_horizontal (HDC hdc, + int x1, + int x2, + int y, + int pen_width, + int *dashes, + int num_dashes) +{ + int n; + for (n = 0; x1 < x2; n++) + { + int len = dashes[n % num_dashes]; + if (x1 + len > x2) + len = x2 - x1; + + if (n % 2 == 0) + if (!PatBlt (hdc, + x1, y - pen_width / 2, + len, pen_width, + PATCOPY)) + { + WIN32_GDI_FAILED ("PatBlt"); + return FALSE; + } + + x1 += dashes[n % num_dashes]; + } +} + + +static inline gboolean +render_line_vertical (HDC hdc, + int x, + int y1, + int y2, + int pen_width, + int *dashes, + int num_dashes) +{ + int n; + for (n = 0; y1 < y2; n++) + { + int len = dashes[n % num_dashes]; + if (y1 + len > y2) + len = y2 - y1; + if (n % 2 == 0) + if (!PatBlt (hdc, + x - pen_width / 2, y1, + pen_width, len, + PATCOPY)) + { + WIN32_GDI_FAILED ("PatBlt"); + return FALSE; + } + y1 += dashes[n % num_dashes]; + } +} + static void gdk_win32_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, @@ -341,16 +404,38 @@ gdk_win32_draw_rectangle (GdkDrawable *drawable, } else { - if (filled) - old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN)); - else - old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH)); - if (old_pen_or_brush == NULL) - WIN32_GDI_FAILED ("SelectObject"); - else if (!Rectangle (hdc, x, y, x+width+1, y+height+1)) - WIN32_GDI_FAILED ("Rectangle"); + if (!filled && gc_private->pen_dashes && !IS_WIN_NT ()) + { + ok = ok && render_line_vertical (hdc, x, y, y+height+1, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + ok = ok && render_line_horizontal (hdc, x, x+width+1, y, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + ok = ok && render_line_vertical (hdc, x+width+1, y, y+height+1, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + ok = ok && render_line_horizontal (hdc, x, x+width+1, y+height+1, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + } else - SelectObject (hdc, old_pen_or_brush); + { + if (filled) + old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN)); + else + old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH)); + if (old_pen_or_brush == NULL) + WIN32_GDI_FAILED ("SelectObject"); + if (!Rectangle (hdc, x, y, x+width+1, y+height+1)) + WIN32_GDI_FAILED ("Rectangle"); + if (old_pen_or_brush) + SelectObject (hdc, old_pen_or_brush); + } } gdk_win32_hdc_release (drawable, gc, mask); @@ -771,57 +856,112 @@ gdk_win32_draw_segments (GdkDrawable *drawable, } else { - const gboolean maybe_patblt = - gc_private->rop2 == R2_COPYPEN && - gc_private->pen_width <= 1 && - (gc_private->pen_style & PS_STYLE_MASK) == PS_SOLID; - - for (i = 0; ok && i < nsegs; i++) - { - /* PatBlt() is much faster than LineTo(), says - * jpe@archaeopteryx.com. Hmm. Use it if we have a solid - * colour pen, then we know that the brush is also solid and - * of the same colour. - */ - if (maybe_patblt && segs[i].x1 == segs[i].x2) + if (gc_private->pen_dashes && !IS_WIN_NT ()) + { + /* code very similar to the IMHO questionable optimization + * below. This one draws dashed vertical/horizontal lines + * with the limited Win9x GDI. --hb + */ + for (i = 0; ok && i < nsegs; i++) { - int y1, y2; - - if (segs[i].y1 <= segs[i].y2) - y1 = segs[i].y1, y2 = segs[i].y2; - else - y1 = segs[i].y2, y2 = segs[i].y1; - - if (!PatBlt (hdc, segs[i].x1, y1, - 1, y2 - y1 + 1, PATCOPY)) - WIN32_GDI_FAILED ("PatBlt"), ok = FALSE; + if (segs[i].x1 == segs[i].x2) + { + int y1, y2; + + if (segs[i].y1 <= segs[i].y2) + y1 = segs[i].y1, y2 = segs[i].y2; + else + y1 = segs[i].y2, y2 = segs[i].y1; + + ok = render_line_vertical (hdc, + segs[i].x1, y1, y2, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + } + else if (segs[i].y1 == segs[i].y2) + { + int x1, x2; + + if (segs[i].x1 <= segs[i].x2) + x1 = segs[i].x1, x2 = segs[i].x2; + else + x1 = segs[i].x2, x2 = segs[i].x1; + + ok = render_line_horizontal (hdc, + x1, x2, segs[i].y1, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + } + else + { + if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL)) + WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE; + if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2)) + WIN32_GDI_FAILED ("LineTo"), ok = FALSE; + + /* Draw end pixel */ + if (ok && gc_private->pen_width <= 1) + if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2)) + WIN32_GDI_FAILED ("LineTo"), ok = FALSE; + } } - else if (maybe_patblt && segs[i].y1 == segs[i].y2) - { - int x1, x2; - - if (segs[i].x1 <= segs[i].x2) - x1 = segs[i].x1, x2 = segs[i].x2; - else - x1 = segs[i].x2, x2 = segs[i].x1; + } + else + { + const gboolean maybe_patblt = + gc_private->rop2 == R2_COPYPEN && + gc_private->pen_width <= 1 && + (gc_private->pen_style & PS_STYLE_MASK) == PS_SOLID; - if (!PatBlt (hdc, x1, segs[i].y1, - x2 - x1 + 1, 1, PATCOPY)) - WIN32_GDI_FAILED ("PatBlt"), ok = FALSE; - } - else + for (i = 0; ok && i < nsegs; i++) { - if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL)) - WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE; - if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2)) - WIN32_GDI_FAILED ("LineTo"), ok = FALSE; - - /* Draw end pixel */ - if (ok && gc_private->pen_width <= 1) - if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2)) - WIN32_GDI_FAILED ("LineTo"), ok = FALSE; + /* PatBlt() is much faster than LineTo(), says + * jpe@archaeopteryx.com. Hmm. Use it if we have a solid + * colour pen, then we know that the brush is also solid and + * of the same colour. + */ + if (maybe_patblt && segs[i].x1 == segs[i].x2) + { + int y1, y2; + + if (segs[i].y1 <= segs[i].y2) + y1 = segs[i].y1, y2 = segs[i].y2; + else + y1 = segs[i].y2, y2 = segs[i].y1; + + if (!PatBlt (hdc, segs[i].x1, y1, + 1, y2 - y1 + 1, PATCOPY)) + WIN32_GDI_FAILED ("PatBlt"), ok = FALSE; + } + else if (maybe_patblt && segs[i].y1 == segs[i].y2) + { + int x1, x2; + + if (segs[i].x1 <= segs[i].x2) + x1 = segs[i].x1, x2 = segs[i].x2; + else + x1 = segs[i].x2, x2 = segs[i].x1; + + if (!PatBlt (hdc, x1, segs[i].y1, + x2 - x1 + 1, 1, PATCOPY)) + WIN32_GDI_FAILED ("PatBlt"), ok = FALSE; + } + else + { + if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL)) + WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE; + if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2)) + WIN32_GDI_FAILED ("LineTo"), ok = FALSE; + + /* Draw end pixel */ + if (ok && gc_private->pen_width <= 1) + if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2)) + WIN32_GDI_FAILED ("LineTo"), ok = FALSE; + } } - } + } } gdk_win32_hdc_release (drawable, gc, mask); } @@ -844,26 +984,69 @@ gdk_win32_draw_lines (GdkDrawable *drawable, hdc = gdk_win32_hdc_get (drawable, gc, mask); - pts = g_new (POINT, npoints); - - for (i = 0; i < npoints; i++) + if (gc_private->pen_dashes && !IS_WIN_NT ()) { - pts[i].x = points[i].x; - pts[i].y = points[i].y; + for (i = 0; i < npoints - 1; i++) + { + if (points[i].x == points[i+1].x) + { + int y1, y2; + if (points[i].y > points[i+1].y) + y1 = points[i+1].y, y2 = points[i].y; + else + y1 = points[i].y, y2 = points[i+1].y; + + render_line_vertical (hdc, points[i].x, y1, y2, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + } + else if (points[i].y == points[i+1].y) + { + int x1, x2; + if (points[i].x > points[i+1].x) + x1 = points[i+1].x, x2 = points[i].x; + else + x1 = points[i].x, x2 = points[i+1].x; + + render_line_horizontal (hdc, x1, x2, points[i].y, + gc_private->pen_width, + gc_private->pen_dashes, + gc_private->pen_num_dashes); + } + else + { + if (!MoveToEx (hdc, points[i].x, points[i].y, NULL)) + WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE; + if (ok && !LineTo (hdc, points[i+1].x, points[i+1].y)) + WIN32_GDI_FAILED ("LineTo"), ok = FALSE; + } + } } + else + { + pts = g_new (POINT, npoints); + + for (i = 0; i < npoints; i++) + { + pts[i].x = points[i].x; + pts[i].y = points[i].y; + } - if (!Polyline (hdc, pts, npoints)) - WIN32_GDI_FAILED ("Polyline"), ok = FALSE; + if (!Polyline (hdc, pts, npoints)) + WIN32_GDI_FAILED ("Polyline"), ok = FALSE; - g_free (pts); + g_free (pts); - /* Draw end pixel */ - if (ok && gc_private->pen_width <= 1) - { - MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL); - if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y)) - WIN32_GDI_FAILED ("LineTo"); + /* Draw end pixel */ + if (ok && gc_private->pen_width <= 1) + { + MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL); + if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y)) + WIN32_GDI_FAILED ("LineTo"); + } } + gdk_win32_hdc_release (drawable, gc, mask); } diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c index cefdfd9c98..4d3a04f1ec 100644 --- a/gdk/win32/gdkgc-win32.c +++ b/gdk/win32/gdkgc-win32.c @@ -107,6 +107,9 @@ gdk_gc_win32_finalize (GObject *object) if (win32_gc->values_mask & GDK_GC_STIPPLE) gdk_drawable_unref (win32_gc->stipple); + + if (win32_gc->pen_dashes) + g_free (win32_gc->pen_dashes); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -363,23 +366,30 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values, switch (values->line_style) { case GDK_LINE_SOLID: - win32_gc->pen_style &= ~(PS_STYLE_MASK); + if (win32_gc->pen_dashes) + { + g_free (win32_gc->pen_dashes); + win32_gc->pen_dashes = NULL; + win32_gc->pen_num_dashes = 0; + } + win32_gc->pen_style &= ~(PS_STYLE_MASK); GDK_NOTE (GC, (g_print ("%sps|=LINE_SOLID", s), s = ",")); win32_gc->pen_style |= PS_SOLID; break; case GDK_LINE_ON_OFF_DASH: - case GDK_LINE_DOUBLE_DASH: /* ??? */ - /* Only set the linestyle here, if it isn't already set - * gdk_win32_gc_set_dashes () knows better - */ - if (0 == (win32_gc->values_mask & GDK_GC_LINE_STYLE)) + case GDK_LINE_DOUBLE_DASH: + if (!win32_gc->pen_dashes) { + /* setting to PS_DASH probably isn't correct. If I understand the + * xlib docs correctly it should influence the handling of + * line endings ? --hb + */ win32_gc->pen_style &= ~(PS_STYLE_MASK); - GDK_NOTE (GC, (g_print ("%sps|=DASH", s), - s = ",")); - win32_gc->pen_style |= PS_DASH; - } + GDK_NOTE (GC, (g_print ("%sps|=DASH", s), + s = ",")); + win32_gc->pen_style |= PS_DASH; + } break; } win32_gc->values_mask |= GDK_GC_LINE_STYLE; @@ -468,6 +478,8 @@ _gdk_win32_gc_new (GdkDrawable *drawable, win32_gc->stipple = NULL; win32_gc->pen_style = PS_GEOMETRIC|PS_ENDCAP_FLAT|PS_JOIN_MITER; win32_gc->pen_width = 0; + win32_gc->pen_dashes = NULL; + win32_gc->pen_num_dashes = 0; win32_gc->values_mask = GDK_GC_FUNCTION | GDK_GC_FILL; @@ -586,6 +598,7 @@ gdk_win32_gc_set_dashes (GdkGC *gc, gint n) { GdkGCWin32 *win32_gc; + int i; g_return_if_fail (GDK_IS_GC (gc)); g_return_if_fail (dash_list != NULL); @@ -597,61 +610,11 @@ gdk_win32_gc_set_dashes (GdkGC *gc, win32_gc->pen_style &= ~(PS_STYLE_MASK); - /* - * Set the extended line style. This could be done by - * PS_USERSTYLE and ExtCreatePen; but ONLY on WinNT, - * so let's make a guess (based on the implementation - * in DIA). On Win9x this does only work for lines - * with width one ... - * - * More workarounds for Win9x descibed at: - * http://www.codeguru.com/gdi/dashed.shtml - */ - if (!IS_WIN_NT () && win32_gc->pen_width > 1) - { - GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: not fully supported\n")); - win32_gc->pen_style |= PS_SOLID; - return; - } - - win32_gc->pen_style &= ~PS_STYLE_MASK; - switch (n) - { - case 2: - if ((dash_list[0] == dash_list[1]) && (dash_list[0] > 2)) - { - win32_gc->pen_style |= PS_DASH; - GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DASH (%d,%d)\n", - dash_list[0], dash_list[1])); - } - else - { - win32_gc->pen_style |= PS_DOT; - GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DOT (%d,%d)\n", - dash_list[0], dash_list[1])); - } - break; - - case 4: - win32_gc->pen_style |= PS_DASHDOT; - GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DASHDOT (%d,%d,%d,%d)\n", - dash_list[0], dash_list[1], - dash_list[2], dash_list[3])); - break; - - case 6: - win32_gc->pen_style |= PS_DASHDOTDOT; - GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: PS_DASHDOTDOT (%d,%d,%d,%d,%d,%d)\n", - dash_list[0], dash_list[1], - dash_list[2], dash_list[3], - dash_list[4], dash_list[5])); - break; - - default: - win32_gc->pen_style |= PS_DASH; - GDK_NOTE (GC, g_print ("gdk_win32_gc_set_dashes: no guess for %d dashes\n", n)); - break; - } + win32_gc->pen_style |= (PS_GEOMETRIC | PS_USERSTYLE); + win32_gc->pen_num_dashes = n; + win32_gc->pen_dashes = g_new (DWORD, n); + for (i = 0; i < n; i++) + win32_gc->pen_dashes[i] = dash_list[i]; } void @@ -752,9 +715,14 @@ gdk_gc_copy (GdkGC *dst_gc, gdk_region_destroy (dst_win32_gc->clip_region); if (dst_win32_gc->hcliprgn != NULL) DeleteObject (dst_win32_gc->hcliprgn); + if (dst_win32_gc->pen_dashes) + g_free (dst_win32_gc->pen_dashes); *dst_win32_gc = *src_win32_gc; + if (dst_win32_gc->pen_dashes) + dst_win32_gc->pen_dashes = g_memdup (src_win32_gc->pen_dashes, + sizeof (DWORD) * src_win32_gc->pen_num_dashes); if (dst_win32_gc->hcliprgn) { /* create a new region, to copy to */ @@ -856,10 +824,28 @@ predraw_set_foreground (GdkGC *gc, logbrush.lbColor = fg; logbrush.lbHatch = 0; - if (*ok && (hpen = ExtCreatePen (win32_gc->pen_style, - (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1), - &logbrush, 0, NULL)) == NULL) - WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE; + if (win32_gc->pen_num_dashes > 0 && !IS_WIN_NT ()) + { + /* The Win9x GDI is rather limited so we either draw dotted + * lines ourselve (only horizontal and vertical) or let them + * be drawn solid to avoid implementing a whole line renderer + */ + if (*ok && (hpen = ExtCreatePen ( + (win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID, + (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1), + &logbrush, + 0, NULL)) == NULL) + WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE; + } + else + { + if (*ok && (hpen = ExtCreatePen (win32_gc->pen_style, + (win32_gc->pen_width > 0 ? win32_gc->pen_width : 1), + &logbrush, + win32_gc->pen_num_dashes, + win32_gc->pen_dashes)) == NULL) + WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE; + } if (*ok && SelectObject (win32_gc->hdc, hpen) == NULL) WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE; diff --git a/gdk/win32/gdkkeys-win32.c b/gdk/win32/gdkkeys-win32.c index 394348d3aa..a2858cbde5 100644 --- a/gdk/win32/gdkkeys-win32.c +++ b/gdk/win32/gdkkeys-win32.c @@ -2053,11 +2053,13 @@ gdk_keyval_name (guint keyval) return (gchar *) found->name; } - else + else if (keyval != 0) { sprintf (buf, "%#x", keyval); return buf; } + + return NULL; } static int diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 8b2d0c65a8..4b50fb5183 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -284,6 +284,8 @@ struct _GdkGCWin32 gint graphics_exposures; gint pen_width; DWORD pen_style; + DWORD *pen_dashes; /* use for PS_USERSTYLE or step-by-step rendering */ + gint pen_num_dashes; HANDLE hwnd; /* If a HDC is allocated, for which window, * or what bitmap is selected into it */ -- 2.30.2